package org.wu.framework.lazy.orm.database.sql.expand.database.persistence.factory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wu.framework.core.utils.ObjectUtils;
import org.wu.framework.lazy.orm.core.config.LazyOperationAttribute;
import org.wu.framework.lazy.orm.core.config.enums.LazyDataSourceType;
import org.wu.framework.lazy.orm.core.config.prop.DefaultLazyDataSourceAttribute;
import org.wu.framework.lazy.orm.core.config.prop.LazyDataSourceAttribute;
import org.wu.framework.lazy.orm.core.source.adapter.SourceFactory;
import org.wu.framework.lazy.orm.database.lambda.domain.PersistenceRepository;
import org.wu.framework.lazy.orm.database.lambda.domain.PersistenceRepositoryFactory;
import org.wu.framework.lazy.orm.database.lambda.dynamic.LazyDynamicDatasourceAdapter;
import org.wu.framework.lazy.orm.database.lambda.dynamic.factory.LazyDynamicAdapterFactory;
import org.wu.framework.lazy.orm.database.lambda.dynamic.toolkit.DynamicLazyDSContextHolder;
import org.wu.framework.lazy.orm.database.lambda.stream.LambdaTableType;
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.LazySqlOperation;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.cure.CureAdapter;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.cure.CureAdapterFactory;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.method.LazyOperationMethod;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.proxy.LazyOperationProxy;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.translation.adapter.LazyTranslationAdapter;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.translation.factory.LazyTranslationAdapterFactory;

import javax.sql.DataSource;
import java.util.List;
import java.util.UUID;

/**
 * 创建数据源配置文件
 */
public class LazyDataSourcePropertiesFactory {
    public static Logger log = LoggerFactory.getLogger(LazyDataSourcePropertiesFactory.class);


    /**
     * 创建数据源配置
     *
     * @param url      连接url
     * @param username 用户名
     * @param password 密码
     * @return LazyDataSourceAttribute
     */
    public static LazyDataSourceAttribute createLazyDataSourceProperties(String url, String username, String password) {
        LazyDataSourceAttribute lazyDataSourceAttribute = new DefaultLazyDataSourceAttribute();
        lazyDataSourceAttribute.setUrl(url);
        lazyDataSourceAttribute.setUsername(username);
        lazyDataSourceAttribute.setPassword(password);
        return lazyDataSourceAttribute;
    }

    /**
     * 创建数据源配置
     *
     * @param url      连接url
     * @param username 用户名
     * @param password 密码
     * @param type     数据源驱动类型
     * @param alias    数据源别名
     * @return LazyDataSourceAttribute
     */
    public static LazyDataSourceAttribute createLazyDataSourceProperties(String url, String username, String password, Class<? extends DataSource> type, String alias) {
        LazyDataSourceAttribute lazyDataSourceAttribute = new DefaultLazyDataSourceAttribute();
        lazyDataSourceAttribute.setUrl(url);
        lazyDataSourceAttribute.setUsername(username);
        lazyDataSourceAttribute.setPassword(password);
        lazyDataSourceAttribute.setType(type);
        lazyDataSourceAttribute.setAlias(alias);
        return lazyDataSourceAttribute;
    }

    /**
     * 初始化 schema
     *
     * @param lazyDataSourceAttribute schema 配置
     * @param lazyOperationAttribute 配置参数
     */
    public static void initSchema(LazyDataSourceAttribute lazyDataSourceAttribute, LazyOperationAttribute lazyOperationAttribute) {
        String url = lazyDataSourceAttribute.getUrl();
        String username = lazyDataSourceAttribute.getUsername();
        String password = lazyDataSourceAttribute.getPassword();
        Class<? extends DataSource> type = lazyDataSourceAttribute.getType();

//        String schema = DataSourceUrlParsingUtil.schema(url);
        //        // 解析数据库url信息
        String defaultInformationSchemaUrl = SourceFactory.getDefaultInformationSchemaUrl(url);
        if (ObjectUtils.isEmpty(defaultInformationSchemaUrl)) {
            return;
        }
        String tempDataSourceId = UUID.randomUUID().toString();

        // 创建数据源配置信息
        LazyDataSourceAttribute tempLazyDataSourceAttribute = LazyDataSourcePropertiesFactory.createLazyDataSourceProperties(defaultInformationSchemaUrl, username, password, type, tempDataSourceId);

        // 代理需要用到的方法
        List<LazyOperationMethod> defaultLazyOperationMethod = LazyOperationMethodFactory.createDefaultLazyOperationMethod(lazyOperationAttribute);

        // 动态数据源适配器
        LazyDynamicDatasourceAdapter lazyDynamicAdapter = LazyDynamicAdapterFactory.createLazyDynamicAdapter(tempLazyDataSourceAttribute);

        // 治愈适配器
        CureAdapter cureAdapter = CureAdapterFactory.createCureAdapter(tempLazyDataSourceAttribute);

        // 转译适配器
        LazyTranslationAdapter lazyTranslationAdapter = LazyTranslationAdapterFactory.createLazyTranslationAdapter();

        // orm代理对象
        LazyOperationProxy defaultLazyOperationProxy = LazyOperationProxyFactory.createLazyOperationProxy(defaultLazyOperationMethod, lazyDynamicAdapter, cureAdapter, lazyTranslationAdapter);

        // 可以执行sql的操作对象
        LazySqlOperation tempLazyOperation = LazyOperationProxyFactory.createLazyOperation(defaultLazyOperationProxy);
        // 最终的 LazyLambdaStream 可以灵活使用的对象
        LazyLambdaStream lazyLambdaStream = LazyLambdaStreamFactory.createLazyLambdaStream(tempLazyOperation);

        DynamicLazyDSContextHolder.switchDatasource(tempDataSourceId);
//        String url = lazyDataSourceAttribute.getUrl();
        String schema = SourceFactory.getUrlSchema(url);
//        LazyLambdaStream lazyLambdaStream = LazyLambdaStreamFactory.createLazyLambdaStream(lazyDataSourceAttribute);
        // 创建数据库连接
        PersistenceRepository persistenceRepository = PersistenceRepositoryFactory.create();
        LazyDataSourceType lazyDataSourceType = SourceFactory.getLazyDataSourceType(url);
        String schemaSql = SourceFactory.createSchemaSql(lazyDataSourceType,schema);
        persistenceRepository.setResultClass(Boolean.class);
        persistenceRepository.setExecutionType(LambdaTableType.CREATE);
        persistenceRepository.setQueryString(schemaSql);
        lazyLambdaStream.executeOne(persistenceRepository);
        log.info("初始化创建数据库:【{}】", schema);
        // 关闭数据库dataSource
        lazyDynamicAdapter.closeDataSource(tempDataSourceId);
    }
}
